package com.netdevsdk.demo.liveview.live;

import java.math.BigDecimal;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JOptionPane;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

import com.netdevsdk.demo.NetDemo;
import com.netdevsdk.demo.util.Common;
import com.netdevsdk.lib.NetDEVSDKLib;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_LIVE_STREAM_INDEX_E;
import com.netdevsdk.lib.NetDEVSDKLib.NETDEV_VIDEO_CODE_TYPE_E;

/**
 * @introduction Live video
 * @description Support IPC/NVR/VMS
 */
public class BasicLive {
    
    /**
     * 
     * @introduction Start live preview
     * @description Start live preview and get the video parameters,update them once in three seconds
     *
     */
    public static void startLive() {
        NetDemo.jPanelShowLiveParam.add(NetDemo.jButtonMic);
        NetDemo.jPanelShowLiveParam.add(NetDemo.jSliderLiveMicSound);
        NetDemo.jPanelShowLiveParam.add(NetDemo.jLabelLiveSound2);
        NetDemo.jPanelShowLiveParam.add(NetDemo.jLableLiveMicSound);
        
        if(null != NetDemo.lpPlayHandle) {
            JOptionPane.showMessageDialog(null, "Please stop playing first.");
            return;
        }
        if(null == NetDemo.lpUserID)
        {
            JOptionPane.showMessageDialog(null, "Please Login device first. error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
            return;
        }
        if(NetDemo.ChannelID == 0) {
            JOptionPane.showMessageDialog(null, "Please select an online channel.");
            return;
        }
        int dwStreamType=0;
        switch (NetDemo.comboBoxConfigVideoStreamIndex.getItemAt(NetDemo.comboBoxConfigVideoStreamIndex.getSelectedIndex())) {
            case "MAIN":
                dwStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_MAIN;
                break;
            case "AUX":
                dwStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_AUX;
                break;
            case "THIRD":
                dwStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_THIRD;
                break;
        }
        
        /* 创建实况预览参数并赋值 */
        NetDEVSDKLib.NETDEV_PREVIEWINFO_S stPreviewInfo = new NetDEVSDKLib.NETDEV_PREVIEWINFO_S();
        stPreviewInfo.dwChannelID = NetDemo.ChannelID;
        stPreviewInfo.dwStreamType = dwStreamType;
        stPreviewInfo.dwLinkMode = 1;
        stPreviewInfo.hPlayWnd = Native.getComponentPointer(NetDemo.panelPlayLabel);
        stPreviewInfo.dwFluency = 0;
        stPreviewInfo.dwStreamMode = 0;
        stPreviewInfo.dwLiveMode = 0;
        stPreviewInfo.dwDisTributeCloud = 0;
        stPreviewInfo.dwallowDistribution = 0;

        /* 启动实时预览 */
        NetDemo.lpPlayHandle = NetDemo.netdevsdk.NETDEV_RealPlay(NetDemo.lpUserID, stPreviewInfo, null, null);     
        if(null == NetDemo.lpPlayHandle) {
            JOptionPane.showMessageDialog(null, "RealPlay failed,error code"+NetDemo.netdevsdk.NETDEV_GetLastError());
            NetDemo.lpPlayHandle = null;
            NetDemo.panelPlayLabel.repaint();
        }else {
            NetDemo.isTimer=true;
            NetDemo.jButtonStartLive.setEnabled(false);
            NetDemo.jButtonStopLive.setEnabled(true);
            NetDemo.netdevsdk.NETDEV_SetMuteStatus(NetDemo.lpPlayHandle,1);

            if(NetDemo.lpID2==null) {
                NetDemo.netdevsdk.NETDEV_OpenSound(NetDemo.lpPlayHandle);
            }
            NetDemo.jSliderLiveSound.setValue(120);
            
            Timer MyTimer=new Timer();     
            MyTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    if(!NetDemo.isTimer) {
                        return;
                    }
                    try{
                        /* 获取窗口码率 */
                        IntByReference pdwBitRate = new IntByReference();
                        boolean bRet = NetDemo.netdevsdk.NETDEV_GetBitRate(NetDemo.lpPlayHandle,pdwBitRate);
                        if(!bRet) {
                            System.out.printf("NETDEV_GetBitRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        NetDemo.jLabelBitRateParam.setText(String.valueOf(pdwBitRate.getValue()));
                        
                        /* 获取窗口帧率 */
                        IntByReference pdwFrameRate = new IntByReference();
                        boolean bRet2 = NetDemo.netdevsdk.NETDEV_GetFrameRate(NetDemo.lpPlayHandle,pdwFrameRate);
                        if(!bRet2) {
                            System.out.printf("NETDEV_GetFrameRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        NetDemo.jLabelFrameRate.setText(String.valueOf(pdwFrameRate.getValue()));
                        
                        /* 获取窗口编码格式 */
                        IntByReference pdwVideoEncFmt = new IntByReference();
                        boolean bRet3 = NetDemo.netdevsdk.NETDEV_GetVideoEncodeFmt(NetDemo.lpPlayHandle,pdwVideoEncFmt);
                        if(!bRet3)
                        {
                            System.out.printf("NETDEV_GetVideoEncodeFmt failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        String showEncodeFmt=null;
                        if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_MJPEG){
                            showEncodeFmt="MJPEG";
                        }else if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_H264) {
                            showEncodeFmt="H.264";
                        }else if(pdwVideoEncFmt.getValue()==NETDEV_VIDEO_CODE_TYPE_E.NETDEV_VIDEO_CODE_H265) {
                            showEncodeFmt="H.265";
                        }
                        NetDemo.jLabelVideoEncodeFmt.setText(showEncodeFmt);
                        
                        /* 获取实况业务流类型 */
                        int dwNewStreamType=0;
                        switch (NetDemo.comboBoxConfigVideoStreamIndex.getItemAt(NetDemo.comboBoxConfigVideoStreamIndex.getSelectedIndex())) {
                            case "MAIN":
                                dwNewStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_MAIN;
                                break;
                            case "AUX":
                                dwNewStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_AUX;
                                break;
                            case "THIRD":
                                dwNewStreamType = NETDEV_LIVE_STREAM_INDEX_E.NETDEV_LIVE_STREAM_INDEX_THIRD;
                                break;
                        }
                        
                        /* 获取实况码流URL */
                        Pointer pszStreamUrl=new Memory(300);
                        boolean bRet4=NetDemo.netdevsdk.NETDEV_GetStreamUrl(NetDemo.lpUserID,NetDemo.ChannelID, dwNewStreamType,pszStreamUrl);
                        if(!bRet4)
                        {
                            System.out.printf("NETDEV_GetStreamUrl failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        byte[] getStreamUrl=pszStreamUrl.getByteArray(0, 300);
                        NetDemo.jLabelLiveViewStreamUrl.setText( Common.byteArrayToString(getStreamUrl));
                        
                        /* 获取视频分辨率 */
                        IntByReference pdwWidth = new IntByReference();
                        IntByReference pdwHeight = new IntByReference();
                        boolean bRet5 = NetDemo.netdevsdk.NETDEV_GetResolution(NetDemo.lpPlayHandle,pdwWidth,pdwHeight);
                        if(!bRet5)
                        {
                            System.out.printf("NETDEV_GetResolution failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        NetDemo.jLabelGetpdwWidth.setText(pdwWidth.getValue() +"x");
                        NetDemo.jLabelGetpdwHeight.setText(String.valueOf(pdwHeight.getValue()));

                        /* 获取窗口丢包率 */
                        IntByReference pURLReceivePacketNum = new IntByReference();
                        IntByReference pURLLostPktNum = new IntByReference();
                        boolean bRet6 = NetDemo.netdevsdk.NETDEV_GetLostPacketRate(NetDemo.lpPlayHandle,pURLReceivePacketNum,pURLLostPktNum);
                        if(!bRet6)
                        {
                            System.out.printf("NETDEV_GetLostPacketRate failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        double lostPacketRate=0.0;
                        if(pURLLostPktNum.getValue()==0) {
                            lostPacketRate=0.00;
                        }else {
                            BigDecimal receive=new BigDecimal(pURLReceivePacketNum.getValue());
                            BigDecimal lost=new BigDecimal(pURLLostPktNum.getValue());
                            BigDecimal sum=receive.add(lost);
                            try {
                                BigDecimal result=receive.divide(sum,2,BigDecimal.ROUND_HALF_UP);
                                lostPacketRate=result.doubleValue();
                            } catch (Exception e) {                                  
                                return;
                            }
                        }
                        NetDemo.jLabelGetpulRecvPktNum.setText(String.valueOf(lostPacketRate));

                        /* 获取静音状态 */
                        IntByReference pbMute=new IntByReference();
                        boolean bRet7= NetDemo.netdevsdk.NETDEV_GetMuteStatus(NetDemo.lpPlayHandle, pbMute);
                        if(!bRet7) {
                            System.out.printf("NETDEV_GetMuteStatus failed:%d\n", NetDemo.netdevsdk.NETDEV_GetLastError());
                            return;
                        }
                        NetDemo.getMute=pbMute.getValue();
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                    
                }
                
            }, 1000, 3000);
        
        }
    }

/**
  * 
  * @introduction stop live
  * @description Stop live and clear text data
  * 
  */
    public static void stopLive() {
        if(null != NetDemo.lpPlayHandle){
            NetDemo.netdevsdk.NETDEV_StopRealPlay(NetDemo.lpPlayHandle);
            setComponents();
            }
        NetDemo.jButtonStartLive.setEnabled(true);
        NetDemo.jButtonStopLive.setEnabled(false);
    }
    
/**
 * 
 * @introduction Set the label of video parameter null
 * @description
 */
    public static void setComponents() {       
            NetDemo.isTimer=false;
            NetDemo.jLabelFrameRate.setText(null);
            NetDemo.jLabelBitRateParam.setText(null);
            NetDemo.jLabelVideoEncodeFmt.setText(null);
            NetDemo.jLabelGetpdwWidth.setText(null);
            NetDemo.jLabelGetpdwHeight.setText(null);
            NetDemo.jLabelGetpulRecvPktNum.setText(null);
            NetDemo.jLabelLiveViewStreamUrl.setText(null);
            NetDemo.lpPlayHandle = null;
            NetDemo.panelPlayLabel.repaint();
    }
}
